package ballena.activities;

import ballena.geolocalizacion.*;
import ballena.utiles.Global;
import ballena.utiles.Servlet;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

public class Geolocalizacion extends MapActivity {
	private MapController mapController;
	private MapView mapView;
	private LocationManager locationManager;
	List<Overlay> mapOverlays;
	Drawable drawable;
	ItemizedOverlay itemizedOverlayTesoro, itemizedOverlayPosicion, itemizedOverlayFavorito;
	private Road mRoad;
	public double flat, flon;
	public int longitudCasa, latitudCasa=0, longitudUsuario, latitudUsuario, longitudGps, latitudGps,
				longitudFavo, latitudFavo;
	public int agregar = 0, agregarDestinoGps = 0, contador=0, contFavoritos=0;
	public GeoPoint p;
	Thread t;
	public boolean salir=false, amigos=false, agregarFavoritos=false, aCasa=false, gps=false, confirmaPunto=false;

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		menu.add(Menu.NONE, 1, 1, R.string.locaAmigos);
		menu.add(Menu.NONE, 2, 2, R.string.agregarPuntos);
		menu.add(Menu.NONE, 3, 3, R.string.modBorracho);
		menu.add(Menu.NONE, 4, 4, R.string.gps);
		menu.add(Menu.NONE, 5, 5, R.string.confirmarPunto);
		return true;
	}

	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		super.onMenuItemSelected(featureId, item);
		switch (item.getItemId()) {

		case 1:
			amigos=!amigos;
			mapOverlays = mapView.getOverlays();
			if (mapOverlays.isEmpty()){}
			else
				mapOverlays.clear();
			break;

		case 2:
			agregarFavoritos=!agregarFavoritos;
			mapOverlays = mapView.getOverlays();
			if (mapOverlays.isEmpty()){}
			else
				mapOverlays.clear();
			break;
		
		case 3:
			aCasa=!aCasa;
			mapOverlays = mapView.getOverlays();
			if (mapOverlays.isEmpty()){}
			else
				mapOverlays.clear();
			break;
			
		case 4:
			gps=!gps;
			mapOverlays = mapView.getOverlays();
			if (mapOverlays.isEmpty()){}
			else
				mapOverlays.clear();
			break;
			
		case 5:
			try {
				servletEnviarFavoritos(latitudFavo, longitudFavo);
			} catch (IOException e) {
				e.printStackTrace();
			}
			break;
		}
		return true;
	}

	

	public void onCreate(Bundle bundle) {
		super.onCreate(bundle);
		setContentView(R.layout.main); 

		
		mapView = (MapView) findViewById(R.id.mapview);
		mapView.setBuiltInZoomControls(true);
		mapView.setSatellite(true);
		mapController = mapView.getController();

		locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,
				0, new GeoUpdateHandler());
		t = new Thread() {
			public void run() {
				while (salir == false) {
					
					if (amigos == true) {
						try {
							servletObtenerPosicionAmigos(Global.usuario.getId());
							Thread.sleep(3000);
							mapOverlays = mapView.getOverlays();
							mapOverlays.clear();
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (IOException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						}
					}
					if (agregarFavoritos == true) {
						
							double fromLat = 38.444444, fromLon = -4.444444, toLat = 38.444444, toLon = -4.444444;
							String url = RoadProvider.getUrl(fromLat, fromLon,
									toLat, toLon);
							InputStream is = getConnection(url);
							mRoad = RoadProvider.getRoute(is);
							mHandler.sendEmptyMessage(0);
							contFavoritos++;
							
						
					}
					if (aCasa == true) {

						try {
							servletObtenerPosicionUsuario(Global.usuario.getId());
							Thread.sleep(1000);
							if (latitudCasa==0)
								servletObtenerPosicionCasa(Global.usuario.getId());
							//Thread.sleep(1000);
							if (latitudUsuario != 0 && longitudUsuario != 0) {
								double fromLat = latitudUsuario / 1E6, fromLon = longitudUsuario / 1E6, toLat = latitudCasa / 1E6, toLon = longitudCasa / 1E6;
								String url = RoadProvider.getUrl(fromLat,
										fromLon, toLat, toLon);
								InputStream is = getConnection(url);
								mRoad = RoadProvider.getRoute(is);
								mHandler.sendEmptyMessage(0);
								Thread.sleep(3000);
								/*mapOverlays = mapView.getOverlays();
								int n = mapOverlays.lastIndexOf(itemizedOverlayTesoro);
								if (n >= 0)
									mapOverlays.remove(n);*/
							} 
								
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (IOException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						}
					}
					if (gps == true){
						try {
							
							servletObtenerPosicionUsuario(Global.usuario.getId());
							Thread.sleep(3000);
							if ((contador == 0) && (latitudUsuario!=0)) {
								double fromLat = latitudUsuario / 1E6, fromLon = longitudUsuario / 1E6, toLat = latitudUsuario / 1E6, toLon = longitudUsuario / 1E6;
								String url = RoadProvider.getUrl(fromLat,fromLon, toLat, toLon);
								InputStream is = getConnection(url);
								mRoad = RoadProvider.getRoute(is);
								mHandler.sendEmptyMessage(0);
								contador++;
							}
							if ((latitudUsuario != 0 && longitudUsuario != 0) && (agregarDestinoGps>=1)) {
								
								//pinta(latitudGps, longitudGps,4,"0");
								double fromLat = latitudUsuario / 1E6, fromLon = longitudUsuario / 1E6, toLat = latitudGps / 1E6, toLon = longitudGps / 1E6;
								String url = RoadProvider.getUrl(fromLat, fromLon, toLat, toLon);
								InputStream is = getConnection(url);
								Thread.sleep(2000);
								mRoad = RoadProvider.getRoute(is);
								Thread.sleep(5000);
								mHandler.sendEmptyMessage(0);
								Thread.sleep(2000);
								
							} else {
								//Toast.makeText(getBaseContext(),"Posición inválida del usuario",5000).show();
							}
								
						} catch (InterruptedException e) {
							e.printStackTrace();
						} catch (IOException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						}
					
					}
				}
			}
		};
		t.start();
		
	}

	public Bitmap getBitmapFromURL(String src) {

		Bitmap bm = null;

		try {
			URL url = new URL(src);
			HttpURLConnection connection = (HttpURLConnection) url
					.openConnection();
			connection.setDoInput(true);
			connection.connect();
			InputStream input = connection.getInputStream();
			Bitmap myBitmap = BitmapFactory.decodeStream(input);
			bm = myBitmap;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
		return bm;
	}

	public void pinta(int latitud, int longitud, int caso, String rutaImgAmigo) {
		
		mapOverlays = mapView.getOverlays();
		switch (caso) {
		case 0: // Dibuja Amigo
			drawable = new BitmapDrawable(Bitmap.createScaledBitmap(getBitmapFromURL
					("http://laballenasc.uphero.com/"+rutaImgAmigo),48,48,true)); 
			itemizedOverlayTesoro = new ItemizedOverlay(drawable);
			GeoPoint tesoro = new GeoPoint (latitud, longitud);

			OverlayItem overlayTesoro = new OverlayItem(tesoro, "", "");

			itemizedOverlayTesoro.addOverlay(overlayTesoro);
			mapOverlays.add(itemizedOverlayTesoro);
			break;
		case 1:  //Dibuja Usuario
			drawable = this.getResources().getDrawable(R.drawable.eu);
			itemizedOverlayTesoro = new ItemizedOverlay(drawable);

			tesoro = new GeoPoint (latitud, longitud);

			overlayTesoro = new OverlayItem(tesoro, "", "");

			itemizedOverlayTesoro.addOverlay(overlayTesoro);
			mapOverlays.add(itemizedOverlayTesoro);
			break;
		case 2: //Dibuja Casa Usuario
			drawable = this.getResources().getDrawable(R.drawable.casa32);
			itemizedOverlayTesoro = new ItemizedOverlay(drawable);

			tesoro = new GeoPoint (latitud, longitud);

			overlayTesoro = new OverlayItem(tesoro, "", "");

			itemizedOverlayTesoro.addOverlay(overlayTesoro);
			mapOverlays.add(itemizedOverlayTesoro);
			break;
		case 3: //Dibuja Favorito al pulsar el mapa
			drawable = this.getResources().getDrawable(R.drawable.favo);
			itemizedOverlayFavorito = new ItemizedOverlay(drawable);

			GeoPoint favorito = new GeoPoint (latitud, longitud);

			OverlayItem overlayFavorito = new OverlayItem(favorito, "", "");

			itemizedOverlayFavorito.addOverlay(overlayFavorito);
			mapOverlays.add(itemizedOverlayFavorito);
			break;
		case 4: // Dibuja destino GPS
			drawable = this.getResources().getDrawable(R.drawable.bandera);
			itemizedOverlayFavorito = new ItemizedOverlay(drawable);

			favorito = new GeoPoint (latitudGps, longitudGps);

			overlayFavorito = new OverlayItem(favorito, "", "");

			itemizedOverlayFavorito.addOverlay(overlayFavorito);
			mapOverlays.add(itemizedOverlayFavorito);
			break;
		}
	}
	
	
	public void servletObtenerPosicionAmigos (int idUsuario) throws IOException{
		
		String param[] = {"idUsuario=" + idUsuario};
		Servlet s = new Servlet(Global.SERVLETOBTENERLOCAMIGOS2, param);
		s.conectar();
		
		InputStream in = s.getInputStream();
		DataInputStream dos = new DataInputStream(in);
		String nAmigos = dos.readLine();
		int n = Integer.parseInt(nAmigos);
		for (int i = 0; i < n; i++) {
			String rutaImagenAmigo = dos.readLine();
			String latitud = dos.readLine();
			String longitud = dos.readLine();
			if (latitud.equals("null") || longitud.equals("null")) {} 
			else {
				
				int ilatitud = Integer.parseInt(latitud);
				int ilongitud = Integer.parseInt(longitud);
				pinta(ilatitud, ilongitud, 0,rutaImagenAmigo);
			}

		}
		dos.close();
	}

	public void servletObtenerPosicionCasa(int idUsuario) throws IOException {

		String param[] = { "idUsuario=" + idUsuario };
		Servlet s = new Servlet(Global.SERVLETOBTENERCASA, param);
		s.conectar();

		InputStream in = s.getInputStream();
		DataInputStream dos = new DataInputStream(in);
		
			String latitud = dos.readLine();
			latitudCasa=Integer.parseInt(latitud);
			String longitud = dos.readLine();
			longitudCasa=Integer.parseInt(longitud);
			if (latitud.equals("null") || longitud.equals("null")) {
			} else {
				int ilatitud = Integer.parseInt(latitud);
				int ilongitud = Integer.parseInt(longitud);
				pinta(ilatitud, ilongitud,2,"0");
			}
			dos.close();
	}
	
	public void servletObtenerPosicionUsuario(int idUsuario) throws IOException {

		String param[] = { "idUsuario=" + idUsuario };
		Servlet s = new Servlet(Global.SERVLETOBTENERLOCUSUARIO, param);
		s.conectar();

		InputStream in = s.getInputStream();
		DataInputStream dos = new DataInputStream(in);

		String latitud = dos.readLine();
		String longitud = dos.readLine();
		if ((!latitud.equals("null")) && (!longitud.equals("null"))) {
			latitudUsuario = Integer.parseInt(latitud);
			longitudUsuario = Integer.parseInt(longitud);
			pinta(latitudUsuario, longitudUsuario, 1,"0");
		} else {
			latitudUsuario = 0;
			longitudUsuario = 0;
		}
		dos.close();
	}
	
	public void servletEnviarFavoritos (int latitud, int longitud) throws IOException {

		String param[] = { "idUsuario=" + Global.usuario.getId(), "latitud="+ latitud, "longitud="+ longitud };
		Servlet s = new Servlet(Global.SERVLETENVIARFAVORITOS, param);
		s.conectar();

		InputStream in = s.getInputStream();
		DataInputStream dos = new DataInputStream(in);

		dos.close();
	}

	Handler mHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			TextView textView = (TextView) findViewById(R.id.description);
			textView.setText(mRoad.mName + " " + mRoad.mDescription);
			MapOverlay mapOverlay = new MapOverlay(mRoad, mapView);
			List<Overlay> listOfOverlays = mapView.getOverlays();
			if (agregarFavoritos==false)
				listOfOverlays.clear();
			listOfOverlays.add(mapOverlay);
			mapView.invalidate();
		}
	};

	private InputStream getConnection(String url) {
		InputStream is = null;
		try {
			URLConnection conn = new URL(url).openConnection();
			is = conn.getInputStream();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return is;
	}

	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}

	public class GeoUpdateHandler implements LocationListener {

		@Override
		public void onLocationChanged(Location location) {

		}

		@Override
		public void onProviderDisabled(String provider) {
		}

		@Override
		public void onProviderEnabled(String provider) {
		}

		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {
		}
	}

	class MapOverlay extends com.google.android.maps.Overlay {
		Road mRoad;
		ArrayList<GeoPoint> mPoints;

		public MapOverlay(Road road, MapView mv) {
			mRoad = road;
			if (road.mRoute.length > 0) {
				mPoints = new ArrayList<GeoPoint>();
				for (int i = 0; i < road.mRoute.length; i++) {
					mPoints.add(new GeoPoint(
							(int) (road.mRoute[i][1] * 1000000),
							(int) (road.mRoute[i][0] * 1000000)));
				}
				int moveToLat = (mPoints.get(0).getLatitudeE6() + (mPoints.get(
						mPoints.size() - 1).getLatitudeE6() - mPoints.get(0)
						.getLatitudeE6()) / 2);
				int moveToLong = (mPoints.get(0).getLongitudeE6() + (mPoints
						.get(mPoints.size() - 1).getLongitudeE6() - mPoints
						.get(0).getLongitudeE6()) / 2);
				GeoPoint moveTo = new GeoPoint(moveToLat, moveToLong);

				mapController = mv.getController();
				//mapController.animateTo(moveTo);
				// mapController.setZoom(18);
			}
		}

		@Override
		public boolean onTouchEvent(MotionEvent event, MapView mapView) {

			if (agregarFavoritos == true) {
				if (event.getAction() == 1) {
					mapOverlays = mapView.getOverlays();
					int n = mapOverlays.lastIndexOf(itemizedOverlayFavorito);
					if (n >= 0)
						mapOverlays.remove(n);
					p = mapView.getProjection().fromPixels((int) event.getX(),
							(int) event.getY());

					latitudFavo = p.getLatitudeE6();
					longitudFavo = p.getLongitudeE6();
					if (contFavoritos>=1)
						pinta(p.getLatitudeE6(), p.getLongitudeE6(), 3,"0");
				}
			}
			if (gps==true){
				if (agregarDestinoGps == 0) {
					if (event.getAction() == 1) {
						p = mapView.getProjection().fromPixels(
								(int) event.getX(), (int) event.getY());
						latitudGps = p.getLatitudeE6();
						longitudGps = p.getLongitudeE6();
						agregarDestinoGps++;
					}
				} else {
					if (event.getAction() == 1) {
						p = mapView.getProjection().fromPixels(
								(int) event.getX(), (int) event.getY());
						latitudGps = p.getLatitudeE6();
						longitudGps = p.getLongitudeE6();
						
					}
				}
			}

			return false;
		}

		@Override
		public boolean draw(Canvas canvas, MapView mv, boolean shadow, long when) {
			super.draw(canvas, mv, shadow);
			drawPath(mv, canvas);
			return true;
		}

		public void drawPath(MapView mv, Canvas canvas)  {
			int x1 = -1, y1 = -1, x2 = -1, y2 = -1;
			Paint paint = new Paint();
			paint.setColor(Color.RED);
			paint.setStyle(Paint.Style.FILL_AND_STROKE);
			paint.setStrokeWidth(3);
			for (int i = 0; i < mPoints.size(); i++) {
				Point point = new Point();
				mv.getProjection().toPixels(mPoints.get(i), point);
				x2 = point.x;
				y2 = point.y;
				if (i > 0) {
					canvas.drawLine(x1, y1, x2, y2, paint);
				}
				x1 = x2;
				y1 = y2;
			}
		}
	}

	@Override
	protected void onResume() {
		super.onResume();
	}

	@Override
	protected void onPause() {
		super.onPause();
	}

	@Override
	protected void onStop() {
		super.onStop();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
	}
}